package com.mall.b2c.hessian.impl;

import java.util.*;

import javax.annotation.Resource;

import com.mall.b2c.cache.GoodsHitRunnable;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;

import org.apache.commons.lang3.StringUtils;
import org.springframework.core.task.TaskExecutor;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import com.google.common.collect.Lists;
import com.mall.b2c.bean.GoodsBean;
import com.mall.b2c.bean.GoodsBuyRecordBean;
import com.mall.b2c.bean.GoodsCategoryBean;
import com.mall.b2c.domain.goods.GoodsCategoryDomain;
import com.mall.b2c.domain.goods.GoodsDomain;
import com.mall.b2c.domain.member.MemberDomain;
import com.mall.b2c.domain.order.OrderItemDomain;
import com.mall.b2c.enums.OrderStatus;
import com.mall.b2c.hessian.GoodsHessian;
import com.mall.b2c.plugin.search.GoodsSearchPluginBundle;
import com.mall.b2c.plugin.search.SearchSelector;
import com.mall.b2c.service.GoodsCategoryService;
import com.mall.b2c.service.GoodsSearchService;
import com.mall.b2c.service.GoodsService;
import com.mall.b2c.service.LuceneService;
import com.mall.b2c.service.MemberService;
import com.mall.b2c.service.OrderItemService;
import com.mall.common.bean.Pager;
import com.mall.common.bean.SearchFilter;
import com.mall.common.bean.SearchFilter.Operator;
import com.mall.common.exception.NoticeException;
import com.mall.common.hessian.impl.BaseHessianImpl;
import com.mall.common.util.JsonUtil;
import com.mall.common.util.UrlUtils;

@Service("b2cGoodsHessian")
public class GoodsHessianImpl extends BaseHessianImpl implements GoodsHessian {

	@Resource private MemberService memberService;
	@Resource private GoodsService goodsService;
	@Resource private GoodsSearchService goodsSearchService;
	@Resource private GoodsCategoryService goodsCategoryService;
	@Resource private OrderItemService orderItemService;
	@Resource private LuceneService luceneService;
	
	@Resource private GoodsSearchPluginBundle listPluginBundle;
	@Resource private GoodsSearchPluginBundle keywordPluginBundle;

	@Resource private TaskExecutor taskExecutor;
	@Resource private RedisTemplate<String, String> redisTemplate;
	
	@Override
	public String getGoodsCategoryList(Long[] catIds, Boolean isVisible, Long parentId,
			Boolean isRecommend, Integer num, String orderBy) {
		return listToJson(goodsCategoryService.getGoodsCategoryList(catIds, isVisible, parentId, isRecommend, num, orderBy));
	}

	@Override
	public String getCoodsCategoryParent(Long catId) {
		GoodsCategoryDomain cate = goodsCategoryService.find(catId);
		if(catId == null){
			throw new NoticeException("分类不存在");
		}
		return objToJson(new GoodsCategoryBean(cate.getParent()));
	}
	
	@Override
	public String getCoodsCategory(Long catId) {
		GoodsCategoryDomain cate = goodsCategoryService.find(catId);
		if(catId == null){
			throw new NoticeException("分类不存在");
		}
		return objToJson(new GoodsCategoryBean(cate));	
	}
	
	@Override
	public String findPagerData(Long memberId, Long[] goodsCategoryIds,
			String[] goodsCategoryCode, Long brandId, Long[] tagIds,
			Long[] providerIds, Long storeId, Integer page, Integer size) {
		Pager pager = newPager(page, size);
		pager = goodsService.findPager(goodsCategoryIds, goodsCategoryCode, brandId, tagIds, providerIds, true, storeId, null, null, pager);
		List<?> list = pager.getList();
		if(!CollectionUtils.isEmpty(list)){
			List<GoodsBean> beans = Lists.newLinkedList();
			for(Object obj : list){
				GoodsDomain goods = (GoodsDomain) obj;
				beans.add(new GoodsBean(goods, null));
			}
			pager.setList(beans);
		}
		return objToJson(pager);
	}

	@Override
	public String getGoodsData(Long id, String code, Long memberId) {
		GoodsDomain goods = null;
		if(id != null){
			goods = goodsService.find(id);
		}else if(code != null){
			goods = goodsService.get("code", code);
		}
		if(goods == null){
			throw new NoticeException("商品不存在");
		}
		return objToJson(new GoodsBean(goods, null));
	}

	public String getGoodsDetail(Long id, String code, Long memberId) {
		GoodsDomain goods = null;
		MemberDomain member = null;
		if(id != null) {
			goods = goodsService.find(id);
		} else if(StringUtils.isNotBlank(code)) {
			goods = goodsService.get("code", code);

		}
		if(goods == null) {
			throw new NoticeException("商品不存在");
		}
		if(memberId != null){
			member = memberService.find(memberId);
		}
		Map<String, Object> map = new HashMap<String, Object>();
		map.put("goods", new GoodsBean(goods, member));

		//商品点击次数
		taskExecutor.execute(new GoodsHitRunnable(redisTemplate, goods));
		return objToJson(map);
	}
	
	@Override
	public String list(String uri, String keyword, Long memberId, Long storeId, Integer pageNumber, Integer pageSize, String pluginBundle) {
		MemberDomain member = memberService.find(memberId);
		Map<String, String> paramMap = new HashMap<String, String>();
		if(StringUtils.isNotBlank(keyword)) {
			paramMap.put("keyword", keyword.trim().toLowerCase().replace("-", "@@"));
		}
		paramMap.put("storeId", storeId+"");
		String catSegment = UrlUtils.getParamStringValue(uri, "cat");
		Long goodsCategoryId = -1L;
		if(StringUtils.isNotBlank(catSegment)) {
			try {
				goodsCategoryId = Long.valueOf(catSegment);
			} catch(NumberFormatException e) {
			}
		}
		GoodsCategoryDomain goodscategory = goodsCategoryService.find(goodsCategoryId);
		Pager pager = new Pager();
		pager.setPageNumber(pageNumber == null ? 1 : pageNumber);
		pager.setPageSize(pageSize == null ? 20 : pageSize);
		Map<String, Object> result = goodsSearchService.list(uri, paramMap,
				goodscategory, member, pager, getGoodsSearchPluginBundle(pluginBundle));
		result.put("selectedCatList", getSelectedCatList(goodscategory));
		result.put("cateCode", goodscategory.getCode());
		return objToJson(result);
	}
	
	private List<JSONObject> getSelectedCatList(GoodsCategoryDomain cat) {
		List<JSONObject> selectedCatList = new ArrayList<JSONObject>();
		while(cat != null) {
			JSONObject jsonObject = JSONObject.fromObject(new SearchSelector(cat.getName(), "/list-cat-"+cat.getId()+".jhtml", false, false));
			if(cat.getTreeLevel() > 0) {
				JSONArray brothers = new JSONArray();
				for(GoodsCategoryDomain brother : cat.getParent().getChildren()) {
					brothers.add(JSONObject.fromObject(new SearchSelector(brother.getName(), "/list-cat-"+brother.getId()+".jhtml", false, false)));
				}
				jsonObject.put("brothers", brothers);
			}
			selectedCatList.add(0, jsonObject);
			cat = cat.getParent();
		}
		return selectedCatList;
	}
	
	private GoodsSearchPluginBundle getGoodsSearchPluginBundle(String pluginBundle) {
		if(StringUtils.isNotBlank(pluginBundle)) {
			if(pluginBundle.equals("listPluginBundle")) {
				return listPluginBundle;
			} else if(pluginBundle.equals("keywordPluginBundle")) {
				return keywordPluginBundle;
			}
		}
		return null;
	}

	@Override
	public String getGoodsBuyRecords(Long goodsId, Integer pageNumber, Integer pageSize) {
		Pager pager = new Pager();
		pager.setPageNumber(pageNumber != null ? pageNumber : 1);
		pager.setPageSize(pageSize != null ? pageSize : 20);
		List<SearchFilter> filterList = new ArrayList<SearchFilter>();
		filterList.add(new SearchFilter("goods.id", Operator.EQ, goodsId));
		filterList.add(new SearchFilter("order.orderStatus", Operator.NE, OrderStatus.waitBuyerPay));
		pager = orderItemService.findPage(pager, filterList);
		List<?> list = pager.getList();
		if(!CollectionUtils.isEmpty(list)){
			List<GoodsBuyRecordBean> beans = new ArrayList<GoodsBuyRecordBean>();
			for(Object obj : list){
				OrderItemDomain orderItem = (OrderItemDomain) obj;
				beans.add(new GoodsBuyRecordBean(orderItem));
			}
			pager.setList(beans);
		}
		return objToJson(pager);
	}
	
	@Override
	public String getSearchTip(String keyword, Integer count) {
		JSONArray arr = luceneService.searchTip(Arrays.asList(keyword.split(" ")), count);

		if(arr.isEmpty()){
			return null;
		}
		return arr.toString();
	}

	@Override
	public String getGoodsListData(Long goodsCategoryId,
			String goodsCategoryCode, Long brandId, Long tagId, Integer count,
			Boolean hasStock, String orderBy, Long memberId, Long storeId) {
		
		List<GoodsDomain> goodsList = 
				goodsService.findList(null, goodsCategoryId, goodsCategoryCode,
						brandId, tagId, null, true, count, hasStock, storeId, orderBy);
		
		if(!CollectionUtils.isEmpty(goodsList)){
			List<GoodsBean> beans = Lists.newLinkedList();
			for(GoodsDomain goods : goodsList){
				beans.add(new GoodsBean(goods, null));
			}
			return listToJson(beans);
		}
		return null;
	}

	@Override
	public String searchByKeyword(
			String keyword, Map<String, String> filterMap,
			String goodsSort, Integer page, Integer size) {
		if(StringUtils.isBlank(keyword)){
			return null;
		}
		Pager pager = newPager(page, size);
		return JsonUtil.getInstance().obj2json(luceneService.searchIndex(pager, keyword, filterMap, goodsSort));
	}

}
